package com.jingbit.ai.helper;

import android.text.TextUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串辅助类
 *
 * @author Wellsa
 */
public class StringHelper {
    private static final AtomicInteger counter = new AtomicInteger(0);

    public static boolean hasValue(String str) {
        if (str == null || str.equals("") || str.equals("null") || str.length() == 0) {
            return false;
        }
        return true;
    }

    /**
     * 生成唯一编号
     *
     * @param idType
     * @return
     */
    public static long getUniqueId(int idType) {
        long uniqueId = 10000000000000l * idType;
        if (counter.get() > 999999999) {
            counter.set(1);
        }
        uniqueId += System.currentTimeMillis() + counter.incrementAndGet();
        return uniqueId;
    }

    public static String generatedMsg(boolean numberFlag, int length) {
        String retStr = "";
        String strTable = numberFlag ? "1234567890"
                : "1234567890abcdefghijkmnpqrstuvwxyz";
        int len = strTable.length();
        boolean bDone = true;
        do {
            retStr = "";
            int count = 0;
            for (int i = 0; i < length; i++) {
                double dblR = Math.random() * len;
                int intR = (int) Math.floor(dblR);
                char c = strTable.charAt(intR);
                if (('0' <= c) && (c <= '9')) {
                    count++;
                }
                retStr += strTable.charAt(intR);
            }
            if (count >= 2) {
                bDone = false;
            }
        } while (bDone);

        return retStr;
    }

    /**
     * 是否手机号码 移动：134、135、136、137、138、139、150、151、157(TD)、158、159、187、188
     * 联通：130、131、132、152、155、156、185、186 电信：133、153、180、189、（1349卫通）
     * 总结起来就是第一位必定为1，第二位必定为3或5或8，其他位置的可以为0-9
     */
    public static boolean isMobilePhone(String mobiles) {
        String telRegex = "[1][3578]\\d{9}";// "[1]"代表第1位为数字1，"[358]"代表第二位可以为3、5、8中的一个，"\\d{9}"代表后面是可以是0～9的数字，有9位。
        if (!hasValue(mobiles))
            return false;
        else
            return mobiles.matches(telRegex);
    }

    /**
     * @param str    the String to check, may be null
     * @param suffix the suffix to find, may be null
     * @return <code>true</code> if the String ends with the suffix, case
     * sensitive, or both <code>null</code>
     * @see String#endsWith(String)
     * @since 2.4
     */
    public static boolean endsWith(String str, String suffix) {
        return endsWith(str, suffix, false);
    }

    /**
     * @param str        the String to check, may be null
     * @param suffix     the suffix to find, may be null
     * @param ignoreCase inidicates whether the compare should ignore case (case
     *                   insensitive) or not.
     * @return <code>true</code> if the String starts with the prefix or both
     * <code>null</code>
     * @see String#endsWith(String)
     */
    private static boolean endsWith(String str, String suffix,
                                    boolean ignoreCase) {
        if (str == null || suffix == null) {
            return (str == null && suffix == null);
        }
        if (suffix.length() > str.length()) {
            return false;
        }
        int strOffset = str.length() - suffix.length();
        return str.regionMatches(ignoreCase, strOffset, suffix, 0,
                suffix.length());
    }

    /**
     * @param str    the String to check, may be null
     * @param suffix the suffix to find, may be null
     * @return <code>true</code> if the String ends with the suffix, case
     * insensitive, or both <code>null</code>
     * @see String#endsWith(String)
     * @since 2.4
     */
    public static boolean endsWithIgnoreCase(String str, String suffix) {
        return endsWith(str, suffix, true);
    }

    /**
     * <p>
     *
     * @param str    the source String to search, may be null
     * @param remove the String to search for and remove, may be null
     * @return the substring with the string removed if found, <code>null</code>
     * if null String input
     * @since 2.1
     */
    public static String removeEnd(String str, String remove) {
        if (isEmpty(str) || isEmpty(remove)) {
            return str;
        }
        if (str.endsWith(remove)) {
            return str.substring(0, str.length() - remove.length());
        }
        return str;
    }

    /**
     * @param str    the source String to search, may be null
     * @param remove the String to search for (case insensitive) and remove, may be
     *               null
     * @return the substring with the string removed if found, <code>null</code>
     * if null String input
     * @since 2.4
     */
    public static String removeEndIgnoreCase(String str, String remove) {
        if (isEmpty(str) || isEmpty(remove)) {
            return str;
        }
        if (endsWithIgnoreCase(str, remove)) {
            return str.substring(0, str.length() - remove.length());
        }
        return str;
    }

    /**
     * @param str    the source String to search, may be null
     * @param remove the String to search for and remove, may be null
     * @return the substring with the string removed if found, <code>null</code>
     * if null String input
     * @since 2.1
     */
    public static String removeStart(String str, String remove) {
        if (isEmpty(str) || isEmpty(remove)) {
            return str;
        }
        if (str.startsWith(remove)) {
            return str.substring(remove.length());
        }
        return str;
    }

    /**
     * @param str    the source String to search, may be null
     * @param remove the String to search for (case insensitive) and remove, may be
     *               null
     * @return the substring with the string removed if found, <code>null</code>
     * if null String input
     * @since 2.4
     */
    public static String removeStartIgnoreCase(String str, String remove) {
        if (isEmpty(str) || isEmpty(remove)) {
            return str;
        }
        if (startsWithIgnoreCase(str, remove)) {
            return str.substring(remove.length());
        }
        return str;
    }

    /**
     * @param str    the String to check, may be null
     * @param prefix the prefix to find, may be null
     * @return <code>true</code> if the String starts with the prefix, case
     * sensitive, or both <code>null</code>
     * @see String#startsWith(String)
     * @since 2.4
     */
    public static boolean startsWith(String str, String prefix) {
        return startsWith(str, prefix, false);
    }

    /**
     * @param str    the String to check, may be null
     * @param prefix the prefix to find, may be null
     * @return <code>true</code> if the String starts with the prefix, case
     * insensitive, or both <code>null</code>
     * @see String#startsWith(String)
     * @since 2.4
     */
    public static boolean startsWithIgnoreCase(String str, String prefix) {
        return startsWith(str, prefix, true);
    }

    /**
     * @param str        the String to check, may be null
     * @param prefix     the prefix to find, may be null
     * @param ignoreCase inidicates whether the compare should ignore case (case
     *                   insensitive) or not.
     * @return <code>true</code> if the String starts with the prefix or both
     * <code>null</code>
     * @see String#startsWith(String)
     */
    private static boolean startsWith(String str, String prefix,
                                      boolean ignoreCase) {
        if (str == null || prefix == null) {
            return (str == null && prefix == null);
        }
        if (prefix.length() > str.length()) {
            return false;
        }
        return str.regionMatches(ignoreCase, 0, prefix, 0, prefix.length());
    }

    public static String packetId() {
        return UUID.randomUUID().toString();
    }

    /**
     * 定义分割常量 （#在集合中的含义是每个元素的分割，|主要用于map类型的集合用于key与value中的分割）
     */
    private static final String SEP1 = "#";
    private static final String SEP2 = "|";

    /**
     * List转换String
     *
     * @param list :需要转换的List
     * @return String转换后的字符串
     */
    public static String listToString(List<?> list) {
        StringBuffer sb = new StringBuffer();
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                if (list.get(i) == null || list.get(i) == "") {
                    continue;
                }
                // 如果值是list类型则调用自己
                if (list.get(i) instanceof List) {
                    sb.append(listToString((List<?>) list.get(i)));
                    sb.append(SEP1);
                } else if (list.get(i) instanceof Map) {
                    sb.append(mapToString((Map<?, ?>) list.get(i)));
                    sb.append(SEP1);
                } else {
                    sb.append(list.get(i));
                    sb.append(SEP1);
                }
            }
        }
        return "L" + sb.toString();
    }

    /**
     * Map转换String
     *
     * @param map :需要转换的Map
     * @return String转换后的字符串
     */
    public static String mapToString(Map<?, ?> map) {
        StringBuffer sb = new StringBuffer();
        // 遍历map
        for (Object obj : map.keySet()) {
            if (obj == null) {
                continue;
            }
            Object key = obj;
            Object value = map.get(key);
            if (value instanceof List<?>) {
                sb.append(key.toString() + SEP1 + listToString((List<?>) value));
                sb.append(SEP2);
            } else if (value instanceof Map<?, ?>) {
                sb.append(key.toString() + SEP1
                        + mapToString((Map<?, ?>) value));
                sb.append(SEP2);
            } else {
                sb.append(key.toString() + SEP1 + value.toString());
                sb.append(SEP2);
            }
        }
        return "M" + sb.toString();
    }

    /**
     * String转换Map
     *
     * @param mapText :需要转换的字符串
     * @return Map<?, ?>
     */
    public static Map<String, Object> stringToMap(String mapText) {

        if (mapText == null || mapText.equals("")) {
            return null;
        }
        mapText = mapText.substring(1);
        Map<String, Object> map = new HashMap<String, Object>();
        String[] text = mapText.split("\\" + SEP2); // 转换为数组
        for (String str : text) {
            String[] keyText = str.split(SEP1); // 转换key与value的数组
            if (keyText.length < 1) {
                continue;
            }
            String key = keyText[0]; // key
            String value = keyText[1]; // value
            if (value.charAt(0) == 'M') {
                Map<?, ?> map1 = stringToMap(value);
                map.put(key, map1);
            } else if (value.charAt(0) == 'L') {
                List<?> list = stringToList(value);
                map.put(key, list);
            } else {
                map.put(key, value);
            }
        }
        return map;
    }

    /**
     * String转换List
     *
     * @param listText :需要转换的文本
     * @return List<?>
     */
    public static List<Object> stringToList(String listText) {
        if (listText == null || listText.equals("")) {
            return null;
        }
        listText = listText.substring(1);

        List<Object> list = new ArrayList<Object>();
        String[] text = listText.split(SEP1);
        for (String str : text) {
            if (str.charAt(0) == 'M') {
                Map<?, ?> map = stringToMap(str);
                list.add(map);
            } else if (str.charAt(0) == 'L') {
                List<?> lists = stringToList(str);
                list.add(lists);
            } else {
                list.add(str);
            }
        }
        return list;
    }

    // 根据Unicode编码完美的判断中文汉字和符号
    private static boolean isChinese(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
            return true;
        }
        return false;
    }

    // 完整的判断中文汉字和符号
    public static boolean isChinese(String strName) {
        char[] ch = strName.toCharArray();
        for (int i = 0; i < ch.length; i++) {
            char c = ch[i];
            if (isChinese(c)) {
                return true;
            }
        }
        return false;
    }

    // 只能判断部分CJK字符（CJK统一汉字）
    public static boolean isChineseByREG(String str) {
        if (str == null) {
            return false;
        }
        Pattern pattern = Pattern.compile("[\\u4E00-\\u9FBF]+");
        return pattern.matcher(str.trim()).find();
    }

    // 只能判断部分CJK字符（CJK统一汉字）
    public static boolean isChineseByName(String str) {
        if (str == null) {
            return false;
        }
        // 大小写不同：\\p 表示包含，\\P 表示不包含
        // \\p{Cn} 的意思为 Unicode 中未被定义字符的编码，\\P{Cn} 就表示 Unicode中已经被定义字符的编码
        String reg = "\\p{InCJK Unified Ideographs}&&\\P{Cn}";
        Pattern pattern = Pattern.compile(reg);
        return pattern.matcher(str.trim()).find();
    }

    public static float getPercent(float num1, float total) {
        // 创建一个数值格式化对象
        NumberFormat numberFormat = NumberFormat.getInstance();
        // 设置精确到小数点后2位
        numberFormat.setMaximumFractionDigits(2);
        String result = numberFormat.format((float) num1 / (float) total * 100);
        result = result.replaceAll(",", "");
        if (result != null && result.equals("NaN"))
            return 0.0f;
        return Float.parseFloat(result);
    }

    /**
     * 字符串设置*
     *
     * @param str
     * @param start
     * @param end
     * @return
     */
    public static String getMask(String str, int start, int end) {
        char[] chars = str.toCharArray();
        StringBuffer sb = new StringBuffer();
        for (int vari = 0; vari < chars.length; vari++) {
            if (vari >= start &&
                    vari <= end) {
                sb.append('*');
            } else {
                sb.append(chars[vari]);
            }
        }
        return sb.toString();
    }

    //第一种实现方式
    private static String longestCommonSubstring(String strA, String strB) {
        char[] chars_strA = strA.toCharArray();
        char[] chars_strB = strB.toCharArray();
        int m = chars_strA.length;
        int n = chars_strB.length;
        int[][] matrix = new int[m + 1][n + 1];
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (chars_strA[i - 1] == chars_strB[j - 1])
                    matrix[i][j] = matrix[i - 1][j - 1] + 1;
                else
                    matrix[i][j] = Math.max(matrix[i][j - 1], matrix[i - 1][j]);
            }
        }
        char[] result = new char[matrix[m][n]];
        int currentIndex = result.length - 1;
        while (matrix[m][n] != 0) {
            if (matrix[n] == matrix[n - 1])
                n--;
            else if (matrix[m][n] == matrix[m - 1][n])
                m--;
            else {
                result[currentIndex] = chars_strA[m - 1];
                currentIndex--;
                n--;
                m--;
            }
        }
        return new String(result);
    }

    private static boolean charReg(char charValue) {
        return (charValue >= 0x4E00 && charValue <= 0X9FA5) || (charValue >= 'a' && charValue <= 'z') || (charValue >= 'A' && charValue <= 'Z') || (charValue >= '0' && charValue <= '9');
    }

    private static String removeSign(String str) {
        StringBuffer sb = new StringBuffer();
        for (char item : str.toCharArray()) {
            if (charReg(item)) {
                sb.append(item);
            }
        }
        return sb.toString();
    }

    /**
     * 快速比较俩个字符串的相似度
     *
     * @param strA 较长的字符串
     * @param strB 较短的字符串
     * @return 俩个字符串的相似度
     * <p>summary</p>:较长的字符串放到前面有助于提交效率
     */
    public static double similarDegree(String strA, String strB) {
        String newStrA = removeSign(strA);
        String newStrB = removeSign(strB);
        int temp = Math.max(newStrA.length(), newStrB.length());
        int temp2 = longestCommonSubstring(newStrA, newStrB).length();
        return temp2 * 1.0 / temp;
    }

    //第二种实现方式
    private static int compare(String str, String target) {
        int[][] d; // 矩阵
        int n = str.length();
        int m = target.length();
        int i; // 遍历str的
        int j; // 遍历target的
        char ch1; // str的
        char ch2; // target的
        int temp; // 记录相同字符,在某个矩阵位置值的增量,不是0就是1
        if (n == 0) {
            return m;
        }
        if (m == 0) {
            return n;
        }
        d = new int[n + 1][m + 1];
        for (i = 0; i <= n; i++) { // 初始化第一列
            d[i][0] = i;
        }

        for (j = 0; j <= m; j++) { // 初始化第一行
            d[0][j] = j;
        }

        for (i = 1; i <= n; i++) { // 遍历str
            ch1 = str.charAt(i - 1);
            // 去匹配target
            for (j = 1; j <= m; j++) {
                ch2 = target.charAt(j - 1);
                if (ch1 == ch2) {
                    temp = 0;
                } else {
                    temp = 1;
                }

                // 左边+1,上边+1, 左上角+temp取最小
                d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + temp);
            }
        }
        return d[n][m];
    }

    private static int min(int one, int two, int three) {
        return (one = one < two ? one : two) < three ? one : three;
    }

    /**
     * 获取字符串的相似度
     *
     * @param str
     * @param target
     * @return
     */
    public static double similarityRatio(String str, String target) {
        return 1 - (double) compare(str, target) / Math.max(str.length(), target.length());
    }

//    /**
//     * 获取字符串编码
//     *
//     * @param str 需要处理的字符串
//     */
//    public static String simpleEncoding(String str) {
//        try{
//            byte[] bs = str.getBytes(SysUtil.JVM_ENCODING);
//            if(str.equals(new String(bs,CharsetUtil.UTF_8))){
//                return CharsetUtil.UTF_8;
//            }
//            if(str.equals(new String(bs,CharsetUtil.GBK))){
//                return CharsetUtil.GBK;
//            }
//            if(str.equals(new String(bs,"ISO-8859-1"))){
//                return "ISO-8859-1";
//            }
//        }catch(UnsupportedEncodingException e) {
//            System.out.println("111111111");
//            e.printStackTrace();
//        }
//        String encode = "GB2312";
//
//        try {
//            if (str.equals(new String(str.getBytes(encode), encode))) {
//                return encode;
//            }
//        } catch (UnsupportedEncodingException e) {
//            e.printStackTrace();
//        }
//
//        encode = "ISO-8859-1";
//        try {
//            if (str.equals(new String(str.getBytes(encode), encode))) {
//                return encode;
//            }
//        } catch (UnsupportedEncodingException exception1) {
//            exception1.printStackTrace();
//        }
//        encode = "UTF-8";
//        try {
//            if (str.equals(new String(str.getBytes(encode), encode))) {
//                return encode;
//            }
//        } catch (UnsupportedEncodingException exception1) {
//            exception1.printStackTrace();
//        }
//        encode = "GBK";
//        try {
//            if (str.equals(new String(str.getBytes(encode), encode))) {
//                return encode;
//
//            }
//        } catch (UnsupportedEncodingException exception1) {
//            exception1.printStackTrace();
//        }
//        return "";
//    }

    /**
     * 判断一个字符串是否为null或空值.
     *
     * @param str 指定的字符串
     * @return
     */
    public static boolean isEmpty(String str) {
        return str == null || str.trim().length() == 0;
    }

    /**
     * 判断是否不是空
     *
     * @param str 指定的字符串
     * @return
     */
    public static boolean isNotEmpty(String str) {
        return str != null && str.trim().length() != 0;
    }

    /**
     * 是否是纯数字.
     *
     * @param str 指定的字符串
     * @return
     */
    public static boolean isNumber(String str) {
        boolean isNumber = false;
        String expr = "^[0-9]+$";
        if (str.matches(expr)) {
            isNumber = true;
        }
        return isNumber;
    }

    /**
     * 是否只是字母和数字.
     *
     * @param str 指定的字符串
     * @return
     */
    public static boolean isNumberLetter(String str) {
        boolean isNoLetter = false;
        String expr = "^[A-Za-z0-9]+$";
        if (str.matches(expr)) {
            isNoLetter = true;
        }
        return isNoLetter;
    }

    /**
     * 判断手机号是否有效
     *
     * @param phone String 手机号码
     * @return boolean 是否有效
     */
    public static boolean isMobileNumber(String phone) {
        if (TextUtils.isEmpty(phone)) {
            return false;
        }
        String regex = "^1[34578]\\d{9}$";
        return phone.matches(regex);
    }

    /**
     * 判断邮箱地址是否有效
     *
     * @param email String 邮箱地址
     * @return boolean 是否有效
     */
    public static boolean isEmailAddress(String email) {
        if (TextUtils.isEmpty(email)) {
            return false;
        }
        String regex = "^[a-zA-Z0-9]+([-_.][a-zA-Z0-9]+)*@[a-zA-Z0-9]+[-a-zA-Z0-9]*(\\.[a-zA-Z0-9]+)*\\.[a-zA-Z]{2,6}$";
        return email.matches(regex);
    }


    /**
     * 判断座机号码是否有效
     *
     * @param number String 座机号码
     * @return boolean 是否有效
     */
    public static boolean isPhoneNumber(String number) {
        if (TextUtils.isEmpty(number)) {
            return false;
        }
        String regex = "^(0\\d{2,3})?\\d{7,8}(\\d{0,6})?$";
        return number.matches(regex);
    }


    /**
     * 描述：手机号格式验证.
     *
     * @param str 指定的手机号码字符串
     * @return 是否为手机号码格式:是为true，否则false
     */
    public static boolean isMobileNo(String str) {
        boolean isMobileNo = false;
        try {
            //13开头
            //Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$");
            Pattern p = Pattern.compile("^(13|14|15|17|18)\\d{9}$");
            Matcher m = p.matcher(str);
            isMobileNo = m.matches();
        } catch (Exception e) {

        }
        return isMobileNo;
    }

    /**
     * 从输入流中获得String.
     *
     * @param is 输入流
     * @return 获得的String
     */
    public static String convertStreamToString(InputStream is) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }

            //最后一个\n删除
            if (sb.indexOf("\n") != -1 && sb.lastIndexOf("\n") == sb.length() - 1) {
                sb.delete(sb.lastIndexOf("\n"), sb.lastIndexOf("\n") + 1);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }

    /**
     * 根据指定的字符把源字符串分割成一个数组
     *
     * @param src
     * @return
     */
    public static List<String> parseString2ListByCustomerPattern(String pattern, String src) {
        if (src == null) {
            return null;
        }
        List<String> list = new ArrayList<String>();
        String[] result = src.split(pattern);
        for (int i = 0; i < result.length; i++) {
            list.add(result[i]);
        }
        return list;
    }

    /**
     * 将字符串转化为int
     *
     * @param s
     * @return
     */
    public static int toInt(String s) {
        int result = 0;
        if (!isEmpty(s)) {
            try {
                result = Integer.parseInt(s);
            } catch (Exception e) {
                // 非数值字符串默认返回0
            }
        }
        return result;
    }


    /**
     * 将字符串转化为long
     *
     * @param s
     * @return
     */
    public static long toLong(String s) {
        long result = 0;
        if (!isEmpty(s)) {
            try {
                result = Long.parseLong(s);
            } catch (Exception e) {

            }
        }
        return result;
    }

    /**
     * 将字符串转化为float
     *
     * @param s
     * @return
     */
    public static Float toFloat(String s) {
        //0.00
        float result = new Float(0);
        if (!isEmpty(s)) {
            try {
                result = Float.parseFloat(s);
            } catch (Exception e) {

            }
        }
        return result;
    }

    /**
     * 将字符串转化为double
     *
     * @param s
     * @return
     */
    public static double toDouble(String s) {
        double result = 0;
        if (!isEmpty(s)) {
            try {
                result = Double.parseDouble(s);
            } catch (Exception e) {

            }
        }
        return result;
    }

    public static String getUUID() {
        return UUID.randomUUID().toString();
    }

    public static String getSimpleUUID() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 校验银行卡卡号
     *
     * @param cardId 卡号
     * @return
     */
    public static boolean isBankcard(String cardId) {
        char bit = getBankCardCheckCode(cardId.substring(0, cardId.length() - 1));
        if (bit == 'N') {
            return false;
        }
        return cardId.charAt(cardId.length() - 1) == bit;
    }

    /**
     * 从不含校验位的银行卡卡号采用 Luhm 校验算法获得校验位
     *
     * @param nonCheckCodeCardId
     * @return
     */
    public static char getBankCardCheckCode(String nonCheckCodeCardId) {
        if (nonCheckCodeCardId == null
                || nonCheckCodeCardId.trim().length() == 0
                || !nonCheckCodeCardId.matches("\\d+")) {
            // 如果传的不是数据返回N
            return 'N';
        }
        char[] chs = nonCheckCodeCardId.trim().toCharArray();
        int luhmSum = 0;
        for (int i = chs.length - 1, j = 0; i >= 0; i--, j++) {
            int k = chs[i] - '0';
            if (j % 2 == 0) {
                k *= 2;
                k = k / 10 + k % 10;
            }
            luhmSum += k;
        }
        return (luhmSum % 10 == 0) ? '0' : (char) ((10 - luhmSum % 10) + '0');
    }

    private static String[] number_zh = new String[]{"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖", "拾"};//拾是多出位
    private static String[] unit_zh = new String[]{"", "拾", "佰", "仟", "萬", "亿"};


    public static String numToZH(Long number) {
        //number_zh unit_zh
        StringBuffer sb = new StringBuffer();

        String str = number.toString();
        Stack<String> _stack = new Stack<String>();
        for (int i = 0; i < str.length(); i++) {
            _stack.push(number_zh[(int) (number % 10)]);// 带 拾、佰、仟...  修改为  (int) (number % 10) + getUnitZH(Long.valueOf(i))
            number = number / 10;
        }
        while (!_stack.isEmpty()) {
            sb.append(_stack.pop());
        }
        return sb.toString();
    }

    private static String getUnitZH(Long num) {
        if (num >= 5 && num < 8) {
            return getUnitZH(num - 4);
        } else if (num > 8) {
            return getUnitZH(num - 8);
        } else if (num == 8) {
            return unit_zh[5]; //亿
        } else if (num > 17) {
            return null;//暂不支持 亿亿
        } else {
            return unit_zh[num.intValue()];
        }
    }
}